package com.wuyan.web.form.api;

import com.wuyan.web.base.aop.ApiLogAnnotation;
import com.wuyan.web.base.helper.BaseApi;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.base.helper.rep.RepBody;
import com.wuyan.web.base.helper.rep.RepHelper;
import com.wuyan.web.base.helper.rep.RepPageData;
import com.wuyan.web.base.helper.req.CustomQueryOrderParams;
import com.wuyan.web.base.helper.req.CustomQueryParams;
import com.wuyan.web.form.helper.FormHelper;
import com.wuyan.web.form.service.FlowService;
import com.wuyan.web.form.service.FormService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.wuyan.web.form.service.FormService.DEF_CFG_ACTIVE_NAME;

@RestController
@RequestMapping("/api/cfg-flow")
@Slf4j
public class FlowApi extends BaseApi implements RepHelper {

    @Autowired
    private FormHelper formHelper;

    @Autowired
    private FormService formService;

    @Autowired
    private FlowService flowService;

    /**
     * 获取流程信息
     *
     * @param id 流程ID
     * @return RepBody<Map>
     */
    @GetMapping("/{id}")
    @ApiLogAnnotation(name = "FLow:get")
    public RepBody<Map> get(@PathVariable("id") String id) {
        String flowTableName = formHelper.getFlowTableName();
        Map data = formService.get(id, flowTableName);
        return ok(data);
    }

    /**
     * 取指定数据的当前处理节点信息
     *
     * @param dataId 数据ID
     * @return RepBody<RepPageData < Map>>
     */
    @GetMapping("/active-node/{dataId}")
    @ApiLogAnnotation(name = "FLow:getNode")
    public RepBody<RepPageData<Map>> getActiveNode(@PathVariable("dataId") String dataId) {
        String flowNodeTableName = formHelper.getFlowNodeTableName();

        List<CustomQueryParams> paramsList = new ArrayList<>();
        List<CustomQueryOrderParams> orderList = new ArrayList<>();

        paramsList.add(CustomQueryParams.builder()
                .left("data_id")
                .op("in")
                .right(dataId.split(","))
                .build());

        paramsList.add(CustomQueryParams.builder()
                .left(DEF_CFG_ACTIVE_NAME)
                .op("eq")
                .right(new Boolean[]{true})
                .build());

        return ok(formService.page(flowNodeTableName, false, 1, 0,
                paramsList, orderList));
    }

    /**
     * 取指定数据的处理流程
     *
     * @param dataId 数据ID
     * @return RepBody<RepPageData < Map>>
     */
    @GetMapping("/node/{dataId}")
    @ApiLogAnnotation(name = "FLow:getNode")
    public RepBody<RepPageData<Map>> getNode(@PathVariable("dataId") String dataId) {
        String flowNodeTableName = formHelper.getFlowNodeTableName();

        List<CustomQueryParams> paramsList = new ArrayList<>();
        List<CustomQueryOrderParams> orderList = new ArrayList<>();

        paramsList.add(CustomQueryParams.builder()
                .left("data_id")
                .op("in")
                .right(dataId.split(","))
                .build());

        orderList.add(CustomQueryOrderParams.builder()
                .filedName("cfg_sort")
                .orderName("asc")
                .build());

        orderList.add(CustomQueryOrderParams.builder()
                .filedName("operate_time")
                .orderName("asc")
                .build());

        return ok(formService.page(flowNodeTableName, false, 1, 0,
                paramsList, orderList));
    }

    /**
     * 开始新的处理流程
     *
     * @param request 请求体
     * @param data    数据信息
     * @return RepBody<Map < String, Object>>
     * @throws Exception e
     */
    @PostMapping("/start")
    @ApiLogAnnotation(name = "FLow:handle")
    public RepBody<Map<String, Object>> start(HttpServletRequest request, @RequestBody Map<String, Object> data)
            throws Exception {
        LoginInfo loginInfo = getLoginInfo(request);
        return ok(flowService.create(data, loginInfo));
    }

    /**
     * 流程处理
     *
     * @param request 请求体
     * @param table   表单名称
     * @param dataId  数据ID
     * @param lineId  连线ID
     * @param nodeId  节点ID
     * @return RepBody<Boolean>
     * @throws Exception e
     */
    @PostMapping("/{form}/handle/{dataId}/{lineId}-{nodeId}")
    @ApiLogAnnotation(name = "FLow:handle")
    public RepBody<Map<String, Object>> handle(HttpServletRequest request,
                                               @PathVariable("form") String table,
                                               @PathVariable("dataId") String dataId,
                                               @PathVariable("lineId") String lineId,
                                               @PathVariable("nodeId") String nodeId,
                                               @RequestBody Map<String, Object> reqData) throws Exception {
        LoginInfo loginInfo = getLoginInfo(request);
        return ok(flowService.handle(table, dataId, lineId, nodeId, loginInfo, reqData));
    }

    /**
     * 流程处理
     *
     * @param request 请求体
     * @param flowId  流程ID
     * @param dataId  数据ID
     * @param lineId  连线ID
     * @param nodeId  节点ID
     * @return RepBody<Boolean>
     * @throws Exception e
     */
    @PostMapping("/handle/{flowId}/{dataId}/{lineId}-{nodeId}")
    @ApiLogAnnotation(name = "FLow:handleByFlowId")
    public RepBody<Map<String, Object>> handleByFlowId(HttpServletRequest request,
                                                       @PathVariable("flowId") String flowId,
                                                       @PathVariable("dataId") String dataId,
                                                       @PathVariable("lineId") String lineId,
                                                       @PathVariable("nodeId") String nodeId,
                                                       @RequestBody Map<String, Object> reqData) throws Exception {
        LoginInfo loginInfo = getLoginInfo(request);
        return ok(flowService.handleByFlowId
                (flowId, dataId, lineId, nodeId, loginInfo, null, null, reqData));
    }
}
